
#include <string.h>
#include "../lib/data_pool_named.h"
#include <jxos_config.h>
#include "jxos_message_pipe.h"
#include "jxos_malloc.h"
#include "jxos_registry.h"

#if (JXOS_MESSAGE_PIPE_ENABLE == 1)

static DATA_POOL_NAMED_STRUCT message_pipe_handle_list[MESSAGE_PIPE_MAX];
static uint8_t message_pipe_handle_list_count = 0;
JXOS_MALLOC_MEM_POOL_STRUCT message_pipe_handle_list_mem_pool;

void jxos_message_pipe_init(void)
{
    memset(message_pipe_handle_list, 0, sizeof(DATA_POOL_NAMED_STRUCT)*MESSAGE_PIPE_MAX);
    message_pipe_handle_list_mem_pool.mem_pool = (void*)message_pipe_handle_list;
    message_pipe_handle_list_mem_pool.len = sizeof(DATA_POOL_NAMED_STRUCT)*MESSAGE_PIPE_MAX;
    message_pipe_handle_list_mem_pool.offset = 0;
    message_pipe_handle_list_count = 0;
}

JXOS_MESSAGE_PIPE_HANDLE jxos_message_pipe_create(uint8_t* space,
						uint16_t space_len,
						uint8_t data_size,
						char* message_pipe_name)
{
    DATA_POOL_NAMED_STRUCT* h = 0;
    if(jxos_malloc_set_mem_pool(&message_pipe_handle_list_mem_pool) == 0){
        while(1);
    }
    if((space == 0)
        ||(space_len == 0)
        ||(data_size == 0)
        ||(message_pipe_name == 0)
    ||(space_len < data_size)
	||(data_size < 3)){
        return 0;
    }

	if(space_len/data_size > 255){
		space_len = data_size*255;	//make sure the number of mails is less the 255
	}

    h = jxos_malloc(sizeof(DATA_POOL_NAMED_STRUCT));
    if(h != 0){
		if(data_pool_named_init(h, space, space_len, data_size) == 1){
#if (JXOS_REGISTRY_ENABLE == 1)
            if(jxos_registry_register(message_pipe_name, h) == 1){
#endif
                message_pipe_handle_list_count++;
#if (JXOS_REGISTRY_ENABLE == 1)
            }
            else{
                h = 0;
            }
#endif
		}
		else{
			h = 0;
		}
    }

    return (JXOS_MESSAGE_PIPE_HANDLE)h;
}

uint8_t jxos_message_pipe_send(JXOS_MESSAGE_PIPE_HANDLE message_pipe, char* sender_name,
							uint8_t* data_to_send, uint8_t data_to_send_len)
{
    if((message_pipe == 0)
       ||(message_pipe < (void*)(message_pipe_handle_list_mem_pool.mem_pool))
       ||(message_pipe > (void*)(message_pipe_handle_list_mem_pool.mem_pool+message_pipe_handle_list_mem_pool.offset))
	   ||(sender_name == 0)){
        return 0;
    }

	return data_pool_named_write_data((DATA_POOL_NAMED_STRUCT*)message_pipe, sender_name, data_to_send, data_to_send_len);
}

uint8_t jxos_message_pipe_receive(JXOS_MESSAGE_PIPE_HANDLE message_pipe, char* receiver_name,
							uint8_t* receive_buffer, uint8_t* receive_data_len)
{
	uint8_t ret;
    if((message_pipe == 0)
       ||(message_pipe < (void*)(message_pipe_handle_list_mem_pool.mem_pool))
       ||(message_pipe > (void*)(message_pipe_handle_list_mem_pool.mem_pool+message_pipe_handle_list_mem_pool.offset))
	   ||(receiver_name == 0)){
        return 0;
    }

    ret = data_pool_named_read_data((DATA_POOL_NAMED_STRUCT*)message_pipe, receiver_name, 0, receive_buffer, receive_data_len);
	if(ret != 0){
		return data_pool_named_del_data((DATA_POOL_NAMED_STRUCT*)message_pipe, 0, receiver_name);
	}
	else{
        return 0;
	}
}

uint8_t jxos_message_pipe_check_empty(JXOS_MESSAGE_PIPE_HANDLE message_pipe)
{
    if((message_pipe == 0)
       ||(message_pipe < (void*)(message_pipe_handle_list_mem_pool.mem_pool))
       ||(message_pipe > (void*)(message_pipe_handle_list_mem_pool.mem_pool+message_pipe_handle_list_mem_pool.offset))){
        return 0xff;
    }

    return data_pool_named_check_empty((DATA_POOL_NAMED_STRUCT*)message_pipe, 0, 0);
}

uint8_t jxos_message_pipe_check_full(JXOS_MESSAGE_PIPE_HANDLE message_pipe)
{
    if((message_pipe == 0)
       ||(message_pipe < (void*)(message_pipe_handle_list_mem_pool.mem_pool))
       ||(message_pipe > (void*)(message_pipe_handle_list_mem_pool.mem_pool+message_pipe_handle_list_mem_pool.offset))){
        return 0xff;
    }

    return data_pool_named_check_full((DATA_POOL_NAMED_STRUCT*)message_pipe, 0, 0);
}

uint8_t jxos_message_pipe_clean_up(JXOS_MESSAGE_PIPE_HANDLE message_pipe, char* sender_name_or_receiver_name)
{
    if((message_pipe == 0)
       ||(message_pipe < (void*)(message_pipe_handle_list_mem_pool.mem_pool))
       ||(message_pipe > (void*)(message_pipe_handle_list_mem_pool.mem_pool+message_pipe_handle_list_mem_pool.offset))
	   ||(sender_name_or_receiver_name == 0)){
        return 0;
    }

    return data_pool_named_clr_all((DATA_POOL_NAMED_STRUCT*)message_pipe, sender_name_or_receiver_name, sender_name_or_receiver_name);
}

uint8_t jxos_message_pipe_sender_name_register(JXOS_MESSAGE_PIPE_HANDLE message_pipe, char* sender_name)
{
    if((message_pipe == 0)
       ||(message_pipe < (void*)(message_pipe_handle_list_mem_pool.mem_pool))
       ||(message_pipe > (void*)(message_pipe_handle_list_mem_pool.mem_pool+message_pipe_handle_list_mem_pool.offset))
	   ||(sender_name == 0)){
        return 0;
    }

	return data_pool_named_writer_name_register((DATA_POOL_NAMED_STRUCT*)message_pipe, sender_name);
}

uint8_t jxos_message_pipe_receiver_name_register(JXOS_MESSAGE_PIPE_HANDLE message_pipe, char* receiver_name)
{
    if((message_pipe == 0)
       ||(message_pipe < (void*)(message_pipe_handle_list_mem_pool.mem_pool))
       ||(message_pipe > (void*)(message_pipe_handle_list_mem_pool.mem_pool+message_pipe_handle_list_mem_pool.offset))
	   ||(receiver_name == 0)){
        return 0;
    }

	return data_pool_named_reader_name_register((DATA_POOL_NAMED_STRUCT*)message_pipe, receiver_name);
}

uint8_t jxos_message_pipe_sender_name_cancel(JXOS_MESSAGE_PIPE_HANDLE message_pipe, char* sender_name)
{
    if((message_pipe == 0)
       ||(message_pipe < (void*)(message_pipe_handle_list_mem_pool.mem_pool))
       ||(message_pipe > (void*)(message_pipe_handle_list_mem_pool.mem_pool+message_pipe_handle_list_mem_pool.offset))
	   ||(sender_name == 0)){
        return 0;
    }

	return data_pool_named_writer_name_cancel((DATA_POOL_NAMED_STRUCT*)message_pipe, sender_name);
}

uint8_t jxos_message_pipe_receiver_name_cancel(JXOS_MESSAGE_PIPE_HANDLE message_pipe, char* receiver_name)
{
    if((message_pipe == 0)
       ||(message_pipe < (void*)(message_pipe_handle_list_mem_pool.mem_pool))
       ||(message_pipe > (void*)(message_pipe_handle_list_mem_pool.mem_pool+message_pipe_handle_list_mem_pool.offset))
	   ||(receiver_name == 0)){
        return 0;
    }

	return data_pool_named_reader_name_cancel((DATA_POOL_NAMED_STRUCT*)message_pipe, receiver_name);
}

#if (JXOS_REGISTRY_ENABLE == 1)
JXOS_MESSAGE_PIPE_HANDLE jxos_message_pipe_get_handle(char* message_pipe_name)
{
    if(message_pipe_name == 0){
        return 0;
    }
    return (JXOS_MESSAGE_PIPE_HANDLE)jxos_registry_find(message_pipe_name);
}
#endif

uint8_t jxos_message_pipe_check_empty_all(void)
{
	uint8_t i;
	uint16_t num;
	for(i = 0; i < message_pipe_handle_list_count; i++){
		num = data_pool_named_check_data_num(&(message_pipe_handle_list[i]), 0, 0);
		if((num != 0xffff)&&(num != 0)){
			return 0;
		}
	}
	return 1;
}
#endif
